package com.hnx.admin.aurora.aspects;

import com.hnx.admin.aurora.annotation.KeyField;
import com.hnx.admin.aurora.annotation.RepeatTable;
import com.hnx.admin.aurora.annotation.RepeatValidator;
import com.hnx.admin.aurora.annotation.ValidField;
import com.hnx.admin.aurora.api.sys.BusinessRepeatAPI;
import com.hnx.admin.aurora.enums.BusinessType;
import com.hnx.admin.aurora.utils.AnnReflectionUtil;
import com.hnx.admin.aurora.utils.ReflectUtil;
import com.hnx.admin.aurora.web.exception.ReflectionFieldValueException;
import com.hnx.admin.aurora.web.json.FieldInfo;
import com.hnx.admin.aurora.web.json.RepeatEntity;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Objects;

/*
创建人： 倔强的头发
创建时间：2025/6/18
功能描述:

*/
@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class RepeatAspect {
    private final BusinessRepeatAPI businessRepeatAPI;
    /*
     * 反射获取表名
     * */
    private String getTableName(Class<?> aClass) {
        String className = aClass.getName().substring(aClass.getName().lastIndexOf(".") + 1);
        RepeatTable table = aClass.getAnnotation(RepeatTable.class);
        if (Objects.isNull(table)) {
            log.error("请在参数类中【" + className + "】定义表名注解RepeatTable");
            throw new RuntimeException("请在参数类中【" + className + "】定义表名注解RepeatTable");
        }
        String value = table.value();
        if (!StringUtils.hasText(value)) {
            log.error("请在参数类【" + className + "】中注解RepeatTable定义表名");
            throw new RuntimeException("请在参数类【" + className + "】中注解RepeatTable定义表名");
        }
        return value;
    }

    @Before("@annotation(repeatValidator)")
    public void toBefore(JoinPoint jp, RepeatValidator repeatValidator) {
        Object arg = jp.getArgs()[0];
        if (Objects.nonNull(arg)) {
            BusinessType type = repeatValidator.type();
            Class<?> aClass = arg.getClass();
            String tableName = getTableName(aClass);
            String id = null;
            String idValue = null;
            if (type == BusinessType.UPDATE) {
                Field field = AnnReflectionUtil.getAnnotationFields(aClass, KeyField.class).get(0);
                KeyField keyField = field.getAnnotation(KeyField.class);
                id = keyField.value();
                idValue = AnnReflectionUtil.getFieldValue(arg, field).toString();
            }
            List<FieldInfo> fieldInfos = AnnReflectionUtil.getFieldInfo(arg, ValidField.class);
            if (fieldInfos != null && fieldInfos.size() > 0) {
                for (int i = 0; i < fieldInfos.size(); i++) {
                    FieldInfo fieldInfo = fieldInfos.get(i);
                    validField(fieldInfo, tableName, type, id, idValue, arg);
                }
            }
        }
    }

    private void valid(FieldInfo fieldInfo, ValidField annotation, String tableName, BusinessType type, String keyField, String fieldValue) {
        Object oVal = fieldInfo.getValue();
        if (Objects.nonNull(oVal)) {
            if (oVal instanceof String) {
                if (StringUtils.hasText(oVal.toString())) {
                    if (StringUtils.hasText(annotation.table())) {
                        tableName = annotation.table();
                    }
                    RepeatEntity repeatEntity = getEntity(annotation, tableName, type, keyField, fieldValue);
                    repeatEntity.setFieldValue(oVal.toString());
                    if (businessRepeatAPI.existsByField(repeatEntity)) {
                        log.error("重复校验异常，错误提示：" + annotation.msg());
                        throw new RuntimeException(annotation.msg());
                    }
                }
            }
        }
    }

    private void validField(FieldInfo fieldInfo, String tableName, BusinessType type, String keyField, String fieldValue, Object obj) {
        ValidField annotation = (ValidField) fieldInfo.getAnnotation();
        boolean flag = annotation.flag();
        boolean sflag = false;
        if (flag) {
            String fieldName = annotation.validFieldName();
            if (StringUtils.hasText(fieldName)) {
                Object val = ReflectUtil.getFieldNameValue(obj, fieldName).orElseThrow(ReflectionFieldValueException::new);

                String value = annotation.validValue();
                sflag = annotation.validFlag() ? val.equals(value) : !val.equals(value);
            }
        }
        if (!flag || sflag) {
            Object value = ReflectUtil.getFieldNameValue(obj, fieldInfo.getFieldName()).orElse(null);
            if(Objects.nonNull(value)) {
                valid(fieldInfo, annotation, tableName, type, keyField, fieldValue);
            }
        }
    }

    private RepeatEntity getEntity(ValidField annotation, String tableName, BusinessType type, String id, String idValue) {
        RepeatEntity repeatEntity = new RepeatEntity();
        repeatEntity.setTableName(tableName);
        repeatEntity.setFieldName(annotation.column());
        if (type == BusinessType.UPDATE) {
            repeatEntity.setId(id);
            repeatEntity.setIdValue(idValue);
        }
        return repeatEntity;
    }

}
